import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateCategoryDto } from './dto/create-category.dto';
import { UpdateCategoryDto } from './dto/update-category.dto';
import { Category } from './entities/category.entity';
import { Like, Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import arrayToTree from 'src/utils/categoryArrayToTree';

@Injectable()
export class CategoriesService {
  constructor(
    @InjectRepository(Category)
    private readonly categoriesRepository: Repository<Category>,
  ) {}

  async create(createCategoryDto: CreateCategoryDto) {
    const { tree } = createCategoryDto;
    const hasCategory = await this.categoriesRepository.findBy({ tree });
    if (hasCategory.length > 0) throw new HttpException(`分类 #${tree} 已存在`, HttpStatus.CONFLICT);
    const category = this.categoriesRepository.create({ ...createCategoryDto });
    return this.categoriesRepository.save(category);
  }

  async findAll() {
    const categories = await this.categoriesRepository.find();
    return arrayToTree(categories);
  }

  async update(id: number, updateCategoryDto: UpdateCategoryDto) {
    const category = await this.categoriesRepository.preload({
      id,
      ...updateCategoryDto,
    });
    if (!category) throw new HttpException(`未找到分类 #${id}`, HttpStatus.NOT_FOUND);
    return this.categoriesRepository.save(category);
  }

  async remove(id: number) {
    const hasCategory = await this.categoriesRepository.find({
      where: { id },
      relations: ['articles'],
    });

    if (hasCategory.length === 0) throw new HttpException(`未找到分类 #${id}`, HttpStatus.NOT_FOUND);

    if (hasCategory[0]?.articles?.length > 0) throw new HttpException(`该分类下存在文章 #${id}`, HttpStatus.CONFLICT);

    const hasChildren = await this.categoriesRepository.find({
      where: { tree: Like(`${hasCategory[0].tree}|%`) },
    });

    if (hasChildren.length > 0) throw new HttpException(`该分类下存在子分类 #${id}`, HttpStatus.CONFLICT);

    await this.categoriesRepository.delete(id);
    return `删除成功`;
  }
}
